import {getBarcodeImgData} from '@/util/common'
import {printPdf} from '@/util/cLodop'
import {DocDefinition, pageSizeHash, getPdfBase64, TextContent, CallNodeData, getVCellMarginTop, CallTableTextContent} from '@/util/pdf'
import request from '@/api/axios'
import {AxiosPromise} from 'axios'
import {DataRes} from '@/api/config'
import {ResidentList} from './residentArchives'
import {ElMessage} from 'element-plus'
import useUser from '@/store/user'

// 是否是医院内外环境
export enum Situation {
  INNER = 'inner', // 内网环境
  OUTER = 'outer' // 非内网环境
}

// 人员列表参数
export interface CheckupRegisterPapams {
  phyDate?: Array<string> // 体检日期
  startPhyDate?: string // 体检开始时间
  endPhyDate?: string //体检结束时间
  teamId?: string //社区id
  idNo?: string //身份证号
  personName?: string //姓名
  page?: number
  limit?: number
}

// 套餐下的项目组合
export interface RegisterItemGroups {
  id: string // id
  itemGroupId: string // 项目组合id
  itemGroupCode: string // 项目组合编码
  itemGroupName: string // 项目组合名称
  price: number // 项目组合价格
  deptName: string // 科室名称
  isAdditional: number // 是否加项
}

// 体检套餐
export interface RegisterPackage {
  packageId: string // 套餐id
  packageName: string // 套餐名称
  packagePrice: number // 套餐价格
}

// 人员列表
export interface CheckupRegisterList {
  id: string
  checkupNo: string // 体检号
  personName: string //  姓名
  gender: string //  性别
  age: number //  年龄
  idNo: string //  身份证号
  nation: string //  民族
  phone: string //  手机号
  portrait: string //  头像
  teamId: string //  社区id
  teamName: string //  社区名称
  address: string //  地址
  phyDate: string //  体检时间
  pastHistory: string // 既往史
  registerItemGroups: Array<RegisterItemGroups>
  registerPackage: RegisterPackage
  packageId: string // 套餐id
  addItemGroupName: string // 加项名称
  addItemGroupPrice: number // 加项价格
  registerStatus: number // 登记状态
}

// 体检登记
export interface CheckupRegisterForm {
  personName: string // 姓名
  gender: string //性别
  age: number | string //年龄
  idNo: string // 身份证号
  nation: string | number // 民族
  phone: string | number // 手机号
  portrait: string // 头像
  teamId: string // 社区id
  teamName: string // 社区名称
  address: string // 地址
  pastHistory?: string | null // 既往史
  packageId?: string | number // 体检套餐id
  itemGroupIds?: Array<string> //加项的项目组合id集合
}

// 选择套餐
export interface PackageList {
  id: string // 体检套餐id
  packageCode: string // 体检套餐编码
  packageName: string // 体检套餐名称
  packagePrice: number // 套餐价格
  itemGroupVOS: Array<RegisterItemGroups> // 项目组合集合
}

// 获取加项的参数
export interface GetAddItemGroup {
  checkupRegisterId?: string // 登记id，如果有就传，没有就不传
  packageId: string //所选套餐id 必传
}

// 加项列表
export type AddItemGroupList = RegisterItemGroups

// 获取套餐参数
export interface GetPackageList {
  gender: string
  age: number | string
  pastHistory?: string
}

// 体检登记返回数据
export interface CheckupRegister {
  id: string // 体检登记id
  errorMsg?: string // 错误信息
}

/**
 * @description: 获取完成登记的人员列表get请求
 * @param {CheckupRegisterPapams} params
 * @return {*}
 */
export const getCheckupRegisterList = (params: CheckupRegisterPapams): AxiosPromise<DataRes<Array<CheckupRegisterList>>> => {
  return request({
    url: '/api/checkupRegister/selectList',
    method: 'get',
    params
  })
}

/**
 * @description: 登记/新增 post请求
 * @param {object} params situation inner/outer 必填
 * @param {CheckupRegisterForm} data
 * @return {*}
 */
export const saveCheckupRegister = (params: {situation: string}, data: CheckupRegisterForm): AxiosPromise<DataRes<CheckupRegister>> => {
  return request({
    url: '/api/checkupRegister/register',
    method: 'post',
    data,
    params
  })
}

/**
 * @description: 取消登记
 * @param {object} params checkupRegisterId 登记id
 * @return {*}
 */
export const cancelCheckupRegister = (params: {checkupRegisterId: string}): AxiosPromise<DataRes<null>> => {
  return request({
    url: '/api/checkupRegister/cancelRegister',
    method: 'post',
    params
  })
}

/**
 * @description: 选择套餐
 * @return {*}
 */
export const getPackageList = (params?: GetPackageList): AxiosPromise<DataRes<Array<PackageList>>> => {
  return request({
    url: '/api/package/selectAllPackage',
    method: 'get',
    params
  })
}

/**
 * @description: 查询所有套餐
 * @return {*}
 */
export const getAllPackageList = (): AxiosPromise<DataRes<Array<PackageList>>> => {
  return request({
    url: '/api/package/selectPackages',
    method: 'get'
  })
}

/**
 * @description: 获取加项数据
 * @param {GetAddItemGroup} params
 * @return {*}
 */
export const getAddItemGroup = (params: GetAddItemGroup): AxiosPromise<DataRes<Array<AddItemGroupList>>> => {
  return request({
    url: '/api/checkupRegister/selectAddItemGroup',
    method: 'get',
    params
  })
}

/**
 * @description: 加项保存
 * @param {object} params checkupRegisterId登记Id,situation 是否医院内网环境
 * @param {Array} data 加项的项目组合id数组
 * @return {*}
 */
export const saveAddItemGroup = (params: {checkupRegisterId?: string; situation: string}, data: Array<string>): AxiosPromise<DataRes<null>> => {
  return request({
    url: '/api/checkupRegister/addItemGroup',
    method: 'post',
    params,
    data
  })
}

/**
 * @description: 删除加项
 * @param {object} params registerItemGroupId 加项的项目组合id
 * @return {*}
 */
export const deleteAddItemGroup = (params: {registerItemGroupId: string}): AxiosPromise<DataRes<null>> => {
  return request({
    url: '/api/checkupRegister/deleteAddItemGroup',
    method: 'post',
    params
  })
}

/**
 * @description: 根据身份证号查询个人信息
 * @param {object} params idNo 身份证号
 * @return {*}
 */
export const getPersonalByIdNo = (params: {idNo: string}): AxiosPromise<DataRes<ResidentList>> => {
  return request({
    url: '/api/person/selectByIdNo',
    method: 'get',
    params
  })
}

/**
 * @description: 体检登记编辑档案
 * @return {*}
 */
export const savePersonToArchives = (data: Partial<ResidentList>): AxiosPromise<DataRes<null>> => {
  return request({
    url: '/api/checkupRegister/savePerson',
    method: 'post',
    data
  })
}

/**
 * @description: 根据性别、年龄查询对应的套餐
 * @param {object} params
 * @return {*}
 */
export const getDefaultPackage = (params: GetPackageList): AxiosPromise<DataRes<PackageList>> => {
  return request({
    url: '/api/checkupRegister/getDefaultPackage',
    method: 'get',
    params
  })
}

/**
 * @description: 判断内外网环境
 * @param {object} params innerIp 内网环境ip
 * @return {*}
 */
export const getJudgeSituation = (params: {innerIp: string}): AxiosPromise<DataRes<string>> => {
  return request({
    url: '/api/checkupRegister/judgeSituation',
    method: 'get',
    params
  })
}

// 获取打印条码数据
export interface GetPrintBarcodes {
  ids: Array<string> //登记id集合 必传
  itemGroupIds?: Array<string> //加项的项目组合id数组(已登记时传递)
}

// 打印条码数据
export interface PrintBarcodesDataList {
  age: number // 年龄
  barcode: string // 条码
  checkupNo: string // 体检号
  gender: string // 性别
  itemGroupName: string // 项目名称
  personName: string // 姓名
  barcodeImg?: string // 条码图形
}

/**
 * @description: 获取打印条码数据
 * @param {GetPrintBarcodes} params
 * @return {*}
 */
export const getPrintBarcodes = (data: GetPrintBarcodes): AxiosPromise<DataRes<Array<PrintBarcodesDataList>>> => {
  return request({
    url: '/api/checkupRegister/printBarcode',
    method: 'post',
    data
  })
}

// 获取打印引导单数据参数
export type GetPrintGuideSheets = Array<string> //登记id集合 必传

// 指引单表格数据
interface PackageGuideList {
  guideName: string //体检项目
  tips: string // 提示
}

// 套餐数据
interface PackageVO {
  packageGuideList: Array<PackageGuideList>
}

// 打印引导单数据
export interface PrintGuideSheetsDataList {
  age: number // 年龄
  checkupNo: string // 体检号
  gender: string // 性别
  personName: string // 姓名
  barcodeImg?: string // 条码图形
  packageVO: PackageVO // 套餐数据
}

/**
 * @description: 获取打印引导单数据
 * @param {GetPrintGuideSheets} data
 * @return {*}
 */
export const getPrintGuideSheets = (data: GetPrintGuideSheets): AxiosPromise<DataRes<Array<PrintGuideSheetsDataList>>> => {
  return request({
    url: '/api/checkupRegister/printGuide',
    method: 'post',
    data
  })
}

/**
 * @description: 根据数据获取打印条码
 * @param {*} data
 * @return {*}
 */
export const getBarcodeDoc = (data: PrintBarcodesDataList) => {
  // 条码页面
  const barcodeDoc: DocDefinition = {
    //页面尺寸
    pageSize: pageSizeHash['5cm*3cm'],
    //页面外边距
    pageMargins: [5, 5, 5, 0],
    //纸张方向 纵向(默认)或横线
    pageOrientation: 'landscape',
    //元素列表
    content: [
      {
        image: data.barcodeImg || '',
        width: 100,
        height: 30,
        alignment: 'center'
      },
      {text: `${data.barcode || ''}`, alignment: 'center', fontSize: 8},
      {
        text: [
          {
            text: `${data.personName || ''}${' '}`,
            font: 'SourceHanSansCN',
            bold: true,
            fontSize: 8
          },
          {text: `${' '}${data.age || ''}岁${' '}`, fontSize: 8},
          {text: `${' '}${data.gender || ''}${' '}`, fontSize: 8},
          {text: `${' '}${data.checkupNo || ''}`, fontSize: 8}
        ],
        alignment: 'center'
      },
      {text: `${data.itemGroupName || ''}`, alignment: 'center', fontSize: 8}
    ],
    // 默认样式
    defaultStyle: {font: 'MicrosoftYaHei'}
  }
  return barcodeDoc
}

/**
 * @description: 获取条码打印数据
 * @return {*}
 */
const getBarcodesDocs = (dataList: Array<PrintBarcodesDataList>) => {
  const promises: Array<Promise<ArrayBuffer | string | null>> = []
  dataList.forEach((item) => {
    const barcodeImg = item.barcode ? getBarcodeImgData(item.barcode, 133, 40) : ''
    barcodeImg && (item.barcodeImg = barcodeImg)
    promises.push(getPdfBase64(getBarcodeDoc(item), true))
  })
  return promises
}

/**
 * @description: 批量打印条码
 * @return {*}
 */
export const batchPrintBarcodes = (data: Array<PrintBarcodesDataList>) => {
  return Promise.all(getBarcodesDocs(data))
    .then((base64) => {
      base64.forEach((item) => {
        printPdf('barcode', 'print', item as string)
      })
    })
    .catch((err) => {
      ElMessage.error(err)
      console.warn(err)
    })
}

//居中放置 先计算一行中最高的,然后再分别取上边距
const tablePaddingTop = (i: number, node: CallNodeData) => {
  if (i > 0) {
    const margins = getVCellMarginTop(node.table, i)
    const line = node.table.body[i]
    if (margins && line) {
      line.forEach((item, i) => {
        const cell = item as CallTableTextContent
        const marginTop = margins[i]
        if (cell._margin) {
          cell._margin[1] = marginTop
        } else {
          cell._margin = [0, marginTop, 0, 0]
        }
      })
    }
    return 4
  } else {
    return 4
  }
}

/**
 * @description: 根据数据获取打印体检引导单
 * @param {*} data
 * @return {*}
 */
export const getGuideSheetDoc = (data: PrintGuideSheetsDataList) => {
  const tableData: Array<Array<TextContent | string | number>> = [
    // 表头
    ['序号', '体检项目', '提示']
  ]
  // 表格数据
  data.packageVO.packageGuideList.forEach((item, index: number) => {
    tableData.push([index + 1, item.guideName, item.tips])
  })
  // 体检引导单页面
  const guideSheetDoc: DocDefinition = {
    //页面尺寸
    pageSize: pageSizeHash['A4'],
    //页面外边距
    pageMargins: [20, 20, 20, 20],
    //纸张方向 纵向(默认)或横线
    pageOrientation: 'portrait',
    //元素列表
    content: [
      {
        text: `${useUser.setup().store.$state.userOrgInfor?.orgName}健康体检引导单`,
        alignment: 'center',
        fontSize: 18,
        font: 'MicrosoftYaHei',
        bold: true,
        margin: 0
      },
      {
        image: data.barcodeImg || '',
        width: 130,
        height: 35,
        margin: [0, 15, 0, 10],
        alignment: 'center'
      },
      {
        columns: [
          {
            text: `体检号：${data.checkupNo || ''}`,
            width: '40%'
          },
          {
            text: `姓名：${data.personName || ''}`,
            width: '30%'
          },
          {
            text: `性别：${data.gender || ''}`,
            width: '15%'
          },
          {
            text: `年龄：${data.age || ''}岁`,
            width: '15%',
            alignment: 'right'
          }
        ],
        columnGap: 1,
        fontSize: 12
      },
      {
        table: {
          widths: ['10%', '45%', '45%'],
          heights: [],
          body: tableData
        },
        layout: {
          paddingTop: tablePaddingTop,
          paddingBottom: () => 4
        },
        margin: [0, 10, 0, 10],
        alignment: 'center'
      },
      {
        text: '请完成体检后将此引导单交回登记处。',
        alignment: 'left',
        fontSize: 14
      }
    ],
    // 默认样式
    defaultStyle: {font: 'SourceHanSansCN'}
  }
  return guideSheetDoc
}

/**
 * @description: 获取体检单打印数据
 * @return {*}
 */
const getGuideSheetDocs = (dataList: Array<PrintGuideSheetsDataList>) => {
  const promises: Array<Promise<ArrayBuffer | string | null>> = []
  dataList.forEach((item) => {
    const barcodeImg = item.checkupNo ? getBarcodeImgData(item.checkupNo, 173, 46) : ''
    barcodeImg && (item.barcodeImg = barcodeImg)
    promises.push(getPdfBase64(getGuideSheetDoc(item), true))
  })
  return promises
}

/**
 * @description: 批量打印体检单
 * @return {*}
 */
export const batchPrintGuideSheet = (data: Array<PrintGuideSheetsDataList>) => {
  return Promise.all(getGuideSheetDocs(data))
    .then((base64) => {
      base64.forEach((item) => {
        printPdf('pdf', 'print', item as string)
      })
    })
    .catch((err) => {
      ElMessage.error(err)
      console.warn(err)
    })
}
